shared/calendarspec: when mktime() moves us backwards, jump forward
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 22 Mar 2021 11:51:47 +0000 (12:51 +0100)
committerArnaud Rebillout <arnaudr@debian.org>
Mon, 13 Apr 2026 07:18:40 +0000 (14:18 +0700)
commit94d70d13df920b008ab7f2f7b2b5d12511d3e007
tree123b28a96803566eeb39e50f49635206cc05613e
parent81656419ea7866028c559b274ca7cc125a182ba7
shared/calendarspec: when mktime() moves us backwards, jump forward

When trying to calculate the next firing of 'Sun *-*-* 01:00:00', we'd fall
into an infinite loop, because mktime() moves us "backwards":

Before this patch:
tm_within_bounds: good=0 2021-03-29 01:00:00 → 2021-03-29 00:00:00
tm_within_bounds: good=0 2021-03-29 01:00:00 → 2021-03-29 00:00:00
tm_within_bounds: good=0 2021-03-29 01:00:00 → 2021-03-29 00:00:00
...

We rely on mktime() normalizing the time. The man page does not say that it'll
move the time forward, but our algorithm relies on this. So let's catch this
case explicitly.

With this patch:
$ TZ=Europe/Dublin faketime 2021-03-21 build/systemd-analyze calendar --iterations=5 'Sun *-*-* 01:00:00'
Normalized form: Sun *-*-* 01:00:00
    Next elapse: Sun 2021-03-21 01:00:00 GMT
       (in UTC): Sun 2021-03-21 01:00:00 UTC
       From now: 59min left
       Iter. #2: Sun 2021-04-04 01:00:00 IST
       (in UTC): Sun 2021-04-04 00:00:00 UTC
       From now: 1 weeks 6 days left           <---- note the 2 week jump here
       Iter. #3: Sun 2021-04-11 01:00:00 IST
       (in UTC): Sun 2021-04-11 00:00:00 UTC
       From now: 2 weeks 6 days left
       Iter. #4: Sun 2021-04-18 01:00:00 IST
       (in UTC): Sun 2021-04-18 00:00:00 UTC
       From now: 3 weeks 6 days left
       Iter. #5: Sun 2021-04-25 01:00:00 IST
       (in UTC): Sun 2021-04-25 00:00:00 UTC
       From now: 1 months 4 days left

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1941335.

(cherry picked from commit 129cb6e249bef30dc33e08f98f0b27a6de976f6f)

Gbp-Pq: Name shared-calendarspec-when-mktime-moves-us-backwards-jump-f.patch
src/shared/calendarspec.c
src/test/test-calendarspec.c
test/test-functions